package com.ter;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.Vector;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Form extends JPanel implements ActionListener {
	
	private static final long serialVersionUID = 1L;
	private LabeledTextField l1;
	private JLabel l;
	private JComboBox<?> mc;
	
	private static Vector<Double> tVal = new Vector<>();
	private Vector<String> res;
	private Vector<Range> classes;
	private static Vector<Double> diff;
	private static Vector<Range> classesDiff;
	private String nbClass;
	
	private JPanel prin;
	private MyJTableModel model;
	public static String pathfile=null;
	JFileChooser fileChose=new JFileChooser();
	
	public Form(){
		
		
		//load("DonneesMeteo.xls");
			
		//load(pathfile);
		//load();	
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));		//Interface utilisateur de discrétisation
		JPanel p = new JPanel();
		p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
		l1=new LabeledTextField("Nombre de classe: ");
		p.add(l1);
		
		
		JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT,10,10));
		l = new JLabel("Méthode: ");
		p1.add(l);
		String[] m = {"classes d'égale amplitude", "classes d'égale effectif"};
		mc = new JComboBox<Object>(m);
		mc.setSelectedIndex(0);
		p1.add(mc);
		
		p.add(p1);
		
		 prin = new JPanel(new BorderLayout());
		prin.add("North",p);
		
		JPanel p2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		JButton b=new JButton("Valider");
		JButton b1=new JButton("Quitter");
		JButton b2=new JButton("Erengistrer");
		JButton b3=new JButton("Variation");//
		p2.add(b);
		p2.add(b3);
		p2.add(b2);//
		p2.add(b1);
		prin.add("South",p2);
		
		initTable();
		
		b.addActionListener(this);
		b1.addActionListener(this);
		b3.addActionListener(this);
		b2.addActionListener(this);//
		this.add(prin);
		
		/*setContentPane(prin);
		setResizable(false);
		setSize(600,500);
		setTitle("Discrétisation");*/
		setVisible(true);
		//setLocationRelativeTo(null);
		
	}

	public void actionPerformed(ActionEvent e) {
		
				
		if(e.getSource().getClass().getName().equals("javax.swing.JButton"))
		{
			JButton b = (JButton) e.getSource();
			//action de validation de la métohde choisie 
			if(b.getText().equals("Valider"))
			{
				if(l1.getTextField().getText().equalsIgnoreCase(""))
				{
					JOptionPane.showMessageDialog(null, "Veuillez saisir le nombre de classe");
					l1.getTextField().requestFocus();
				}
				/*if(pathfile==null){
					JOptionPane.showMessageDialog(null, "Veuillez valider les données charger");
				}*/
				else 
				{
					
					if(l1.getTextField().getText().matches("[0-9]*"))
					{
						nbClass = l1.getTextField().getText();
						if(mc.getSelectedIndex()==0)
						{
							amplitude(tVal);
							
						}
						else
						{
							effectif();
						}
						
					}
					else
					{
						JOptionPane.showMessageDialog(null, "Veuillez saisir un nombre");
						l1.getTextField().requestFocus();
					}					
				}
			}
			if(b.getText().equals("Quitter"))
			{
				System.exit(0);
			}
			if(b.getText().equals("Erengistrer"))
			{
				affecter();
				try {
					int returnVal = fileChose.showSaveDialog(Form.this);
		            if (returnVal == JFileChooser.APPROVE_OPTION) {
		            	File file = fileChose.getSelectedFile();
		                String topath=file.getAbsolutePath();
						save(topath);	
		            }
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (b.getText().equals("Variation")) {
				nbClass = l1.getTextField().getText();
				changeForm();
			}
		}
	}
	
	public Vector<Range> amplitude(Vector<Double> input){
		
		// Calcul de valeur maximal et minimal du tableau de données
		double maxv = max(input);
		double minv = min(input);
		classes = new Vector<>();
		Integer n = new Integer(nbClass);		
		//Calcule d'amplitude totale 
		Double amplitotate = maxv-minv;
		DecimalFormat df = new DecimalFormat("0000.0000"); 
		String str = df.format(amplitotate); 
		amplitotate = Double.parseDouble(str.replace(',', '.')); 
		//calcul d'etendue des classes
		Double etendue = (Double)amplitotate/n;
		DecimalFormat dff = new DecimalFormat("0000.0000"); 
		String strr = dff.format(etendue); 
		etendue = Double.parseDouble(strr.replace(',', '.')); 					
		//construction d'un tableau intermédiaire des bornes de classes
		double classe[] = new double[n+1];
		double eps = 0.0001;
		classe[0]=minv;
		for (int i = 1; i < classe.length; i++) {
			classe[i]=classe[i-1]+etendue;
		}				
		//construction du tableau des classes é égal amplitude
		Range rr=new Range(classe[0],classe[1]);
		classes.add(rr);		
		for (int i = 1; i <n ; i++) {
			Range r = new Range(classe[i]+(i*eps), classe[i+1]+(i*eps));
			classes.add(r);	
		}		
		//remplir les classes par les valeurs du tableau d'entrée
		remplir(input);
		//affichage des résultats obtenu
		afficher();
		return classes;
	}
	
	public void effectif(){
		//Nombre de classe choisi 
		Integer n = new Integer(nbClass);
		//Calcul d'effectif
		Integer eff = (tVal.size()/n);
		//tableau de données trié
		Vector<Double> teff= new Vector<>();
		classes = new Vector<>();
		for (int i = 0; i < tVal.size(); i++) {
			teff.add(tVal.get(i));
		}		
		Collections.sort(teff);
		//construction d'un tableau intermédiaire des bornes de classes
		Integer classe[] = new Integer[n+1];
		double eps = 0.0001;
		classe[0]=0;
		classe[1]=eff-1;
		classe[n]=tVal.size();
		for (int i = 2; i < (classe.length)-1; i++) {
			classe[i]=(i*eff);
		}
		//construction du tableau des classes é égal effectif
		Range rr=new Range(teff.get(classe[0].intValue()),teff.get(classe[1].intValue()));
		classes.add(rr);		
		for (int i = 1; i <(classe.length)-2 ; i++) {
			
			Range r = new Range(teff.get(classe[i]+1)+eps, teff.get(classe[i+1]));
			classes.add(r);			
		}
		Range rrr=new Range(teff.get(classe[n-1].intValue())+eps,teff.get(classe[n].intValue()-1));
		classes.add(rrr);
		//remplir les classes par les valeurs du tableau d'entrée
		remplir(teff);
		for (int j = 0; j < classes.size(); j++) {
			classes.get(j).setFreqabs(eff);
			classes.get(j).setFreqrel(100/n);
		}
		
		//affichage des résultats obtenu
		afficher();		
	}
	
	public Vector<Double> difference(){
		
		diff = new Vector<>();
		
		for (int i = 0; i < tVal.size()-1; i++) {
			diff.add(tVal.get(i+1)-tVal.get(i));
		}
		
//		System.out.println("tableau des differences: " + diff);
//		System.out.println(tVal.get(0));
//		System.out.println("valeur minimum: " + min(diff) + " " + "valeur maximum: " + max(diff));
//		
//		System.out.println("premiére valeur: " + diff.get(0) + " " + "derniére valeur: " + diff.lastElement());
		return diff;
	}
	
	public Vector<Range> changeForm(){
		difference();
		classes= new Vector<>();
		
		classesDiff = new Vector<>();
		classesDiff= amplitude(diff);		
		//System.out.println("les classes de différence:");
//		for (int i = 0; i < classes.size(); i++) {
//			System.out.println("min Val: " + classes.get(i).getMinval() +  " " + "max Val: " +classes.get(i).getMaxval() );
//		}
		return classesDiff;
	}
	
	public static Vector<Double> getTabDiff(){
		return diff;
	}
	
	public static Vector<Range>  getClassDiff(){
		return classesDiff;
	}
	
	public static void updatepath(String path){
		pathfile=path;
	}
	
	public void remplir(Vector<Double> t){
		
		float n = (float)t.size();
		float s ;
		float r;
		for (int i = 0; i < classes.size(); i++) {
			
			for (int j = 0; j < t.size(); j++) {
				
				if(classes.get(i).contient(t.get(j)))
				{
					classes.get(i).getT().add(t.get(j));
				
				}
			}
			classes.get(i).setFreqabs(classes.get(i).getT().size());
			s=classes.get(i).getFreqabs();
			r=s/n;
			classes.get(i).setFreqrel(r*100);
		}	
		
}
	
	public Vector<String> affecter(){
		
		res = new Vector<>();
		res.setSize(tVal.size());
for (int i = 0; i < classes.size(); i++) {
			
			for (int j = 0; j < tVal.size(); j++) {
				
				if(classes.get(i).contient(tVal.get(j)))
				{
					res.set(j, "C"+i);
				
				}
			}
}
//			System.out.println("classes" + classes.get(0));
//		System.out.println("tVal" + tVal.get(0));
//		System.out.println("res" + res.get(0));
//		System.out.println("tVal" + tVal.lastElement());
//		System.out.println("res" + res.lastElement());
		
		return res;
		
	}
	public void afficher(){
		
			Vector<String> res=new Vector<>();			
			int index = 0;
			model.clearTable();
			for(Range r:classes){
				String line=r.transformer(";");
				
				StringBuffer rowIndex = new StringBuffer("Classe ");
				rowIndex = rowIndex.append(index);
				index++;
				rowIndex =  rowIndex.append(";");
				rowIndex = rowIndex.append(line);
				res.add(rowIndex.toString());
				model.addline(rowIndex.toString(), ";");
			}	 
	}
	
	 public static Vector<Vector<HSSFCell>> read(String fileName)    {
	        Vector<Vector<HSSFCell>> cellVectorHolder = new Vector<Vector<HSSFCell>>();	        
	        try{
	                FileInputStream myInput = new FileInputStream(fileName);
	                POIFSFileSystem myFileSystem = new POIFSFileSystem(myInput);
	            HSSFWorkbook myWorkBook = new HSSFWorkbook(myFileSystem);
	            HSSFSheet mySheet = myWorkBook.getSheetAt(1);
	           Iterator<?> rowIter = mySheet.rowIterator(); 
	           while(rowIter.hasNext()){
	                  HSSFRow myRow = (HSSFRow) rowIter.next();
	                  Iterator<?> cellIter = myRow.cellIterator();
	                  Vector<HSSFCell> cellStoreVector=new Vector<HSSFCell>();
	                  while(cellIter.hasNext()){
	                          HSSFCell myCell = (HSSFCell) cellIter.next();
	                          cellStoreVector.addElement(myCell);
	                  }
	                  cellVectorHolder.addElement(cellStoreVector);
	                  
	          }
	        }catch (Exception e){e.printStackTrace(); }
			return cellVectorHolder;
	       
	 }
	 
	 public static void load(String path){
			
			Vector<Vector<HSSFCell>> dataHolder=read(path);	
			Double resd;
			for (int i = 4; i < dataHolder.size(); i++) {
				 resd = Double.parseDouble(trans(dataHolder.get(i).toString()));
				tVal.add(resd);		
			}
		}
	 
public void save(String path) throws IOException{
	StringBuffer fileContent = new StringBuffer();
	String[] columnNames = {"Borne inferieure","Borne superieure","Frequence absolue","Frequence relative"};
		
	for (int i = 0; i < model.getRowCount(); i++) {
		Object cellValue = model.getValueAt(i, 0);
		 fileContent.append(cellValue);
		 fileContent.append("\n");
		 for (int j = 1; j < 5; j++) {
			 fileContent.append("\t");
			 fileContent.append(columnNames[j-1] + ": ");
			 Object cellValuee = model.getValueAt(i, j);
			 fileContent.append(cellValuee);	
			 fileContent.append("\n");
		}		
	}
	
	fileContent.append("\n");
	fileContent.append("correspondance entre Air temperature et classes de discrétisation");
	fileContent.append("\n");
	fileContent.append("\n");
	fileContent.append("Air temperature");
	fileContent.append("\t");
	fileContent.append("classe");
	fileContent.append("\n");
	for (int i = 0; i < tVal.size(); i++) {
		fileContent.append(tVal.get(i));
		fileContent.append("\t\t\t");
		fileContent.append(res.get(i));
		fileContent.append("\n");
	}
	 
	FileWriter fileWriter = new FileWriter(new File(path));
	fileWriter.write(fileContent.toString());
	fileWriter.flush();
	fileWriter.close();
	JOptionPane.showMessageDialog(null, "vos donnees sauvegarder avec succes dans :\n"+path);
}


public static String trans(String s){
			StringBuffer sb = new StringBuffer();
			StringBuffer ress = new StringBuffer();
			char[] c = new char[10];
			
			sb.append(s);		
			sb.getChars(sb.indexOf(",")+1, sb.indexOf(",", sb.indexOf(",")+1), c, 0);
			ress.append(c);
			return ress.toString();	
		}
		

public void initTable()
	{
		JPanel border = new JPanel(new BorderLayout());
		String[] columnNames = {"", "Borne inférieure","Borne supérieure","Fréquence absolue","Fréquence relative"};
		
		model = new MyJTableModel(columnNames);
		MyJTable table = new MyJTable(model);
		JScrollPane sp=new JScrollPane(table);
		border.add(table.getTableHeader(), BorderLayout.NORTH);
		border.add(sp, BorderLayout.CENTER);
		prin.add(border);
	}
	
	public double max(Vector<Double> tt){
		double maxvaleur = tt.get(0);
		for (int i = 1; i < tt.size(); i++) {

		if (tt.get(i) >= maxvaleur)	maxvaleur = tt.get(i);
		}
		return maxvaleur;	
	}
	
	public double min(Vector<Double> tt){
		double minvaleur = tt.get(0);
		for (int i = 0; i < tt.size(); i++) {
		if (tt.get(i) < minvaleur)
		{
		minvaleur = tt.get(i);
		}
	}
		return minvaleur;
}
	
	public static void main(String[] args) {
		new Form();
		
		}
}
